/**
 * 交叉类型& 功能类似于接口继承，用于组合多个类型为一个类型(通常适用于对象类型)
 * 注意交叉类型的前置是type 类型，而不是接口
 * 后面用来合并的可以是接口也可以是类型
 *
 * 交叉类型和接口继承的不同
 * 1. 实现合并的时候，对于同名的属性，处理冲突的方式不一样
 * 2. 接口继承会直接报错
 * 3. 交叉类型不会报错，但是会出现一些新的情况 而是会合并类型，成为一个联合类型
 *  3.1 比如重名的是基本类型的数据phone,在PersonDetail中phone的类型会成为never
 *  3.2 如果重名的是非基本类型，是可以成功的
 *  3.3 fn的参数最后就是一个联合类型的参数
 *  文献参考：https://blog.csdn.net/qq_36380426/article/details/104386296
 */
interface Person {
  name: string
  //   phone: number
  fn: (val: number) => string
}
interface Contact {
  phone: string
  fn: (val: string) => string
}
type PersonDetail = Person & Contact

let obj: PersonDetail = {
  name: 'tom',
  phone: '123',
  fn(val){
      return val
  }
}
// console.log(obj.fn(123));

interface D { d: boolean; }
interface E { e: string; }
interface F { f: number; }
interface A { x: D; }
interface B { x: E; }
interface C { x: F; }
type ABC = A & B & C;
let abc: ABC = {
    x: {
      d: true,
      e: 'semlinker',
      f: 666
    }
};
console.log('abc:', abc);